package com.molichuxing.gateway.bff.car.services.impl;

import com.moli.iov.util.CommonUtils;
import com.molichuxing.framework.dto.Paged;
import com.molichuxing.framework.result.ResponseResult;
import com.molichuxing.framework.utils.ObjectCastUtil;
import com.molichuxing.gateway.bff.car.entity.response.IllegalAlarmVo;
import com.molichuxing.gateway.bff.car.entity.response.MileageExAlarmsVo;
import com.molichuxing.gateway.bff.car.entity.response.OfflineAlarmVo;
import com.molichuxing.gateway.bff.car.entity.response.WarehouseAlarmVo;
import com.molichuxing.gateway.bff.car.services.CarBffService;
import com.molichuxing.gateway.bff.car.services.IVehicleMonitorBffService;
import com.molichuxing.gateway.utils.TokenUtil;
import com.molichuxing.gateway.utils.entity.UserEntity;
import com.molichuxing.services.business.dto.response.AlarmInfoDto;
import com.molichuxing.services.business.dto.response.CarOrderBizDto;
import com.molichuxing.services.business.dto.response.UserBizDto;
import com.molichuxing.services.business.service.OrderBizService;
import com.molichuxing.services.business.service.UserBizService;
import com.molichuxing.services.business.service.VehicleBizService;
import com.molichuxing.services.infrastructure.dto.response.CarDto;
import com.molichuxing.services.infrastructure.dto.response.DealerDto;
import com.molichuxing.services.infrastructure.dto.response.EntrepotStorageDto;
import com.molichuxing.services.infrastructure.dto.response.IovCarOfflineAlarm;
import com.molichuxing.services.infrastructure.dto.response.StoreDto;
import com.molichuxing.services.infrastructure.service.DealerService;
import com.molichuxing.services.infrastructure.service.EntrepotStorageService;
import com.molichuxing.services.infrastructure.service.FenceStoreStockService;
import com.molichuxing.services.infrastructure.service.IovCarService;
import com.molichuxing.services.infrastructure.service.StoreService;
import com.molichuxing.services.property.FenceStoreStockTypeEnum;
import com.molichuxing.services.property.IovCarControlOperateTypeEnum;
import com.molichuxing.services.property.OrderExclusivelStatusEnum;
import com.molichuxing.services.property.OrderSubscribeStatusEnum;
import com.molichuxing.services.property.OrderTypeEnum;
import io.swagger.annotations.ApiImplicitParam;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;

import javax.annotation.Resource;
import java.time.ZoneOffset;
import java.util.ArrayList;
import java.util.Comparator;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * The type Vehicle monitor service.
 *
 * @author wanghualin
 * @date 2020 -03-31 11:36:30
 */
@Service
@Slf4j
public class VehicleMonitorBffServiceImpl implements IVehicleMonitorBffService {
    @Resource
    private VehicleBizService vehicleBizService;
    @Resource
    private IovCarService iovCarService;
    @Resource
    private CarBffService carBffService;
    @Resource
    private OrderBizService orderBizService;
    @Resource
    private StoreService storeService;
    @Resource
    private UserBizService userBizService;
    @Resource
    private FenceStoreStockService fenceStoreStockService;
    @Resource
    private EntrepotStorageService entrepotStorageService;
    @Resource
    private DealerService dealerService;
    @Resource
    private TokenUtil tokenUtil;

    /**
     * 出围栏
     */
    private final static int OUT_FENCE = 25;
    /**
     * 进围栏
     */
    private final static int IN_FENCE = 26;

    private final static String ASC = "asc";
    private final static String DESC = "desc";

    /**
     * 车辆失联列表
     *
     * @param params
     * @param pageNum
     * @param pageSize
     * @return
     */
    @Override
    public Paged<OfflineAlarmVo> getOfflineAlarmVoList(Map<String, Object> params, Integer pageNum, Integer pageSize) {
        log.info("车辆管理-车辆监控-车辆失联入参:{},pageNum:{},pageSize:{}", params, pageNum, pageSize);
        String vin = ObjectCastUtil.castString(params.get("vin"));
        String beginTime = ObjectCastUtil.castString(params.get("beginTime"));
        String endTime = ObjectCastUtil.castString(params.get("endTime"));
        String license = ObjectCastUtil.castString(params.get("license"));
        Paged<OfflineAlarmVo> paged = new Paged<>();
        paged.setPageNum(pageNum).setPageSize(pageSize);
        List<IovCarOfflineAlarm> iovCarOfflineAlarms = iovCarService.listOfflineAlarmsByVin(vin, beginTime, endTime, license);
        if (CollectionUtils.isEmpty(iovCarOfflineAlarms)) {
            return paged;
        }
        List<IovCarOfflineAlarm> collect = iovCarOfflineAlarms.stream()
                .skip((pageNum - 1) * pageSize)
                .limit(pageSize)
                .collect(Collectors.toList());
        if (CollectionUtils.isEmpty(collect)) {
            return paged;
        }
        /**
         * 组装
         */
        List<OfflineAlarmVo> list = assemblyDate(collect);
        paged.setList(list);
        paged.setTotal(iovCarOfflineAlarms.size());
        return paged;
    }

    /**
     * 里程异变
     *
     * @param params
     * @param pageNum
     * @param pageSize
     * @return
     */
    @Override
    public Paged<MileageExAlarmsVo> getMileageExAlarmsList(Map<String, Object> params, Integer pageNum, Integer pageSize) {
        log.info("车辆管理-车辆监控-里程异变入参:{},pageNum:{},pageSize:{}", params, pageNum, pageSize);
        String license = ObjectCastUtil.castString(params.get("license"));
        String vin = ObjectCastUtil.castString(params.get("vin"));
        String beginTime = ObjectCastUtil.castString(params.get("beginTime"));
        String endTime = ObjectCastUtil.castString(params.get("endTime"));
        Paged<MileageExAlarmsVo> paged = new Paged<>();
        paged.setPageNum(pageNum).setPageSize(pageSize);
        List<AlarmInfoDto> mileage = iovCarService.getMileageExAlarmsList(vin, beginTime, endTime, license);
        log.info("车辆网返回数据：{}", mileage);
        if (CollectionUtils.isEmpty(mileage)) {
            return paged;
        }

        /**
         * 组装
         */
        List<MileageExAlarmsVo> list = assemblyMileageExAlarmsVoDate(mileage);
        if (CollectionUtils.isEmpty(list)) {
            return paged;
        }
        List<MileageExAlarmsVo> collect = list.stream()
                .sorted(Comparator.comparing(MileageExAlarmsVo::getBeginTime).reversed())
                .skip((pageNum - 1) * pageSize)
                .limit(pageSize)
                .collect(Collectors.toList());
        paged.setList(collect);
        paged.setTotal(list.size());
        return paged;
    }

    /**
     * 驶出仓储报警
     *
     * @param params
     * @param pageNum
     * @param pageSize
     * @return
     */
    @Override
    public Paged<WarehouseAlarmVo> getWarehouseAlarmList(Map<String, Object> params, Integer pageNum, Integer pageSize) {
        log.info("车辆管理-车辆监控-驶出仓储报警入参:{},pageNum:{},pageSize:{}", params, pageNum, pageSize);
        String license = ObjectCastUtil.castString(params.get("license"));
        String vin = ObjectCastUtil.castString(params.get("vin"));
        String beginTime = ObjectCastUtil.castString(params.get("beginTime"));
        String endTime = ObjectCastUtil.castString(params.get("endTime"));
        Integer stockId = ObjectCastUtil.castInteger(params.get("stockId"));
        String sortWay = ObjectCastUtil.castString(params.get("sortWay"));
        Paged<WarehouseAlarmVo> paged = new Paged<>();
        paged.setPageNum(pageNum).setPageSize(pageSize);
        List<WarehouseAlarmVo> warehouseAlarmVos = new ArrayList<>();
        //根据中转库查询绑定fenceId
        List<Integer> fenceIds = fenceStoreStockService.getFenceByStoreId(stockId, FenceStoreStockTypeEnum.ENTREPOT_STORAGE);
        if (CollectionUtils.isEmpty(fenceIds)) {
            return paged;
        }
        //获取数据源
        List<AlarmInfoDto> fenceAlarmList = iovCarService.getFenceAlarmList(vin, beginTime, endTime, license, fenceIds);
        log.info("车辆网返回数据：{}", fenceAlarmList);
        if (CollectionUtils.isEmpty(fenceAlarmList)) {
            return paged;
        }
        //得到出围栏报警
        List<AlarmInfoDto> outFenceList = getFenceAlarmInfo(fenceAlarmList, OUT_FENCE);
        if (CollectionUtils.isEmpty(outFenceList)) {
            return paged;
        }
        List<AlarmInfoDto> collect = new ArrayList<>();
        if (StringUtils.isBlank(sortWay) || DESC.equals(sortWay)) {
            /**
             * 得到围栏id
             */
            collect = outFenceList.stream()
                    .sorted(Comparator.comparing(AlarmInfoDto::getBeginTime).reversed())
                    .skip((pageNum - 1) * pageSize)
                    .limit(pageSize)
                    .collect(Collectors.toList());
        } else {
            /**
             * 得到围栏id
             */
            collect = outFenceList.stream()
                    .sorted(Comparator.comparing(AlarmInfoDto::getBeginTime))
                    .skip((pageNum - 1) * pageSize)
                    .limit(pageSize)
                    .collect(Collectors.toList());
        }

        if (CollectionUtils.isEmpty(collect)) {
            return paged;
        }
        /**
         * 组装
         */
        List<WarehouseAlarmVo> list = assemblyWarehouseAlarmVoListDate(collect);

        paged.setList(list);
        paged.setTotal(outFenceList.size());
        return paged;

    }

    /**
     * 驶出驶门店
     *
     * @param params
     * @param pageNum
     * @param pageSize
     * @return
     */
    @Override
    public Paged<WarehouseAlarmVo> getStoresAlarmList(Map<String, Object> params, Integer pageNum, Integer pageSize) {
        log.info("车辆管理-车辆监控-驶出门店报警入参:{},pageNum:{},pageSize:{}", params, pageNum, pageSize);
        String license = ObjectCastUtil.castString(params.get("license"));
        String vin = ObjectCastUtil.castString(params.get("vin"));
        String beginTime = ObjectCastUtil.castString(params.get("beginTime"));
        String endTime = ObjectCastUtil.castString(params.get("endTime"));
        Integer stockId = ObjectCastUtil.castInteger(params.get("stockId"));
        Integer dealerId = ObjectCastUtil.castInteger(params.get("dealerId"));
        String sortWay = ObjectCastUtil.castString(params.get("sortWay"));
        Paged<WarehouseAlarmVo> paged = new Paged<>();
        paged.setPageNum(pageNum).setPageSize(pageSize);
        //得到符合的fenceIds
        List<Integer> stockIds = getStockIds(stockId, dealerId);
        if (CollectionUtils.isEmpty(stockIds)) {
            return paged;
        }
        //得到符合的fenceIds
        List<Integer> fenceIds = fenceStoreStockService.getFenceIdByStoreIds(stockIds, FenceStoreStockTypeEnum.STORE.getValue());
        if (CollectionUtils.isEmpty(fenceIds)) {
            return paged;
        }
        //获取数据源
        List<AlarmInfoDto> fenceAlarmList = iovCarService.getFenceAlarmList(vin, beginTime, endTime, license, fenceIds);
        log.info("车辆网返回数据：{}", fenceAlarmList);
        if (CollectionUtils.isEmpty(fenceAlarmList)) {
            return paged;
        }
        //得到出围栏报警
        List<AlarmInfoDto> outFenceList = getFenceAlarmInfo(fenceAlarmList, OUT_FENCE);
        if (CollectionUtils.isEmpty(outFenceList)) {
            return paged;
        }
        List<AlarmInfoDto> collect = new ArrayList<>();
        if (StringUtils.isBlank(sortWay) || DESC.equals(sortWay)) {
            /**
             * 得到围栏id
             */
            collect = outFenceList.stream()
                    .sorted(Comparator.comparing(AlarmInfoDto::getBeginTime).reversed())
                    .skip((pageNum - 1) * pageSize)
                    .limit(pageSize)
                    .collect(Collectors.toList());
        } else {
            /**
             * 得到围栏id
             */
            collect = outFenceList.stream()
                    .sorted(Comparator.comparing(AlarmInfoDto::getBeginTime))
                    .skip((pageNum - 1) * pageSize)
                    .limit(pageSize)
                    .collect(Collectors.toList());
        }

        if (CollectionUtils.isEmpty(collect)) {
            return paged;
        }
        /**
         * 组装数据
         */
        List<WarehouseAlarmVo> list = assemblyStoresAlarmVoListDate(collect, stockIds, fenceIds);
        paged.setList(list);
        paged.setTotal(outFenceList.size());
        return paged;
    }

    /**
     * 查询非法报警illegal
     *
     * @param params
     * @param pageNum
     * @param pageSize
     * @return
     */
    @Override
    public Paged<IllegalAlarmVo> getIllegalAlarmList(Map<String, Object> params, Integer pageNum, Integer pageSize) {
        log.info("车辆管理-车辆监控-驶入非法区域报警入参:{},pageNum:{},pageSize:{}", params, pageNum, pageSize);
        String license = ObjectCastUtil.castString(params.get("license"));
        String vin = ObjectCastUtil.castString(params.get("vin"));
        String beginTime = ObjectCastUtil.castString(params.get("beginTime"));
        String endTime = ObjectCastUtil.castString(params.get("endTime"));
        String sortWay = ObjectCastUtil.castString(params.get("sortWay"));
        Paged<IllegalAlarmVo> paged = new Paged<>();
        paged.setPageNum(pageNum).setPageSize(pageSize);
        //获取数据源
        List<AlarmInfoDto> fenceAlarmList = iovCarService.getFenceAlarmList(vin, beginTime, endTime, license, null);
        log.info("车辆网返回数据：{}", fenceAlarmList);
        if (CollectionUtils.isEmpty(fenceAlarmList)) {
            return paged;
        }
        //得到出围栏报警
        List<AlarmInfoDto> inFenceList = getFenceAlarmInfo(fenceAlarmList, IN_FENCE);
        if (CollectionUtils.isEmpty(inFenceList)) {
            return paged;
        }
        List<AlarmInfoDto> collect = new ArrayList<>();
        if (StringUtils.isBlank(sortWay) || DESC.equals(sortWay)) {
            /**
             * 得到围栏id
             */
            collect = inFenceList.stream()
                    .sorted(Comparator.comparing(AlarmInfoDto::getBeginTime).reversed())
                    .skip((pageNum - 1) * pageSize)
                    .limit(pageSize)
                    .collect(Collectors.toList());
        } else {
            /**
             * 得到围栏id
             */
            collect = inFenceList.stream()
                    .sorted(Comparator.comparing(AlarmInfoDto::getBeginTime))
                    .skip((pageNum - 1) * pageSize)
                    .limit(pageSize)
                    .collect(Collectors.toList());
        }
        if (CollectionUtils.isEmpty(collect)) {
            return paged;
        }

        /**
         * 组装数据
         */
        List<IllegalAlarmVo> list = assemblyIllegalAlarmListDate(collect);

        paged.setList(list);
        paged.setTotal(inFenceList.size());
        return paged;
    }

    /**
     * 车辆控制命令
     *
     * @param params
     * @return
     */
    @Override
    public ResponseResult sendControlCommand(Map<String, Object> params) {
        String vin = ObjectCastUtil.castString(params.get("vin"));
        Integer operateType = ObjectCastUtil.castInteger(params.get("operateType"));

        try {
            UserEntity user = tokenUtil.getUser();
            Boolean aBoolean = iovCarService.vehicleControlCommand(vin, operateType, user.getAccountId(), user.getAccount());
         /*   if (aBoolean) {
                if (IovCarControlOperateTypeEnum.CONTROL.getValue()==operateType){
                    return new ResponseResult().success("已成功发送锁车请求");
                }else if(IovCarControlOperateTypeEnum.DECONTROL.getValue()==operateType) {
                    return new ResponseResult().success("已成功发送解锁请求");
                }else{
                    return new ResponseResult().success();
                }
            } else {
                if (IovCarControlOperateTypeEnum.CONTROL.getValue()==operateType){
                    return new ResponseResult().error("发送锁车请求失败，可重新发送请求");
                }else if(IovCarControlOperateTypeEnum.DECONTROL.getValue()==operateType) {
                    return new ResponseResult().error("发送解锁请求失败，可重新发送请求");
                }else{
                    return new ResponseResult().error();
                }
            }*/
            if (IovCarControlOperateTypeEnum.CONTROL.getValue()==operateType){
                return new ResponseResult().success("已成功发送锁车请求");
            }else if(IovCarControlOperateTypeEnum.DECONTROL.getValue()==operateType) {
                return new ResponseResult().success("已成功发送解锁请求");
            }else{
                return new ResponseResult().success();
            }
        } catch (Exception e) {
            log.info("控车异常：{}", e.getMessage());
            if (IovCarControlOperateTypeEnum.CONTROL.getValue()==operateType){
                return new ResponseResult().error("发送锁车请求失败，可重新发送请求");
            }else if(IovCarControlOperateTypeEnum.DECONTROL.getValue()==operateType) {
                return new ResponseResult().error("发送解锁请求失败，可重新发送请求");
            }
            return new ResponseResult().error("控车异常");
        }

    }


    /**
     * 组装出围栏数据
     *
     * @param collect
     * @return
     */
    private List<IllegalAlarmVo> assemblyIllegalAlarmListDate(List<AlarmInfoDto> collect) {
        List<IllegalAlarmVo> list = new ArrayList<>();
        List<String> vinList = collect.stream().map(AlarmInfoDto::getVin)
                .collect(Collectors.toList());
        //车是否存在
        List<CarDto> carDtoList = carBffService.getByVinList(vinList);
        if (CollectionUtils.isEmpty(carDtoList)) {
            return list;
        }
        Map<String, CarDto> carDtoMap = new HashMap<>();
        //车型id
        List<Integer> vehicleIds = new ArrayList<>();
        carDtoList.forEach(carDto -> {
            vehicleIds.add(carDto.getVehicleId());
            carDtoMap.put(carDto.getVin(), carDto);
        });
        // 查询车型信息
        Map<Integer, String> vehicleFullName = vehicleBizService.getVehicleFullName(vehicleIds);
        for (AlarmInfoDto alarmInfoDto : collect) {
            IllegalAlarmVo vo = new IllegalAlarmVo();
            CommonUtils.copyProperties(alarmInfoDto, vo);
            vo.setFenceName(alarmInfoDto.getFenceInfo().getFenceName());
            vo.setAlarmType(IN_FENCE);

            CarDto carDto = carDtoMap.get(vo.getVin());
            if (carDto != null) {
                vo.setLicencePlate(carDto.getLicencePlate());
                vo.setVehicleName(vehicleFullName.get(carDto.getVehicleId()));
            }
            list.add(vo);
        }
        return list;

    }

    /**
     * 根据门店查询条件返回绑定围栏id
     *
     * @param stockId  门店id
     * @param dealerId 经销商id
     * @return
     */
    private List<Integer> getStockIds(Integer stockId, Integer dealerId) {
        List<Integer> stock = new ArrayList<>();
        if (dealerId != null && stockId != null) {
            stock.add(stockId);
        } else if (dealerId != null && stockId == null) {
            //得到有效的门店
            List<StoreDto> storeByDealer = storeService.getStoreByDealer(dealerId);
            if (!CollectionUtils.isEmpty(storeByDealer)) {
                for (StoreDto storeDto : storeByDealer) {
                    stock.add(storeDto.getStoreId());
                }
            }
        } else {
            //获取所有门店
            List<StoreDto> storeList = null;
            try {
                storeList = storeService.getAllStoreList(null);
            } catch (Exception e) {
                e.printStackTrace();
            }
            if (!CollectionUtils.isEmpty(storeList)) {
                for (StoreDto storeDto : storeList) {
                    stock.add(storeDto.getStoreId());
                }
            }
        }
        return stock;
    }

    /**
     * 组装门店数据
     *
     * @param collect
     * @return
     */
    private List<WarehouseAlarmVo> assemblyStoresAlarmVoListDate(List<AlarmInfoDto> collect, List<Integer> stockIds, List<Integer> fenceIds) {
        List<WarehouseAlarmVo> warehouseAlarmVos = new ArrayList<>();
        List<String> vinList = collect.stream().map(AlarmInfoDto::getVin)
                .collect(Collectors.toList());
        //车是否存在
        List<CarDto> carDtoList = carBffService.getByVinList(vinList);
        if (CollectionUtils.isEmpty(carDtoList)) {
            return warehouseAlarmVos;
        }
        Map<String, CarDto> carDtoMap = new HashMap<>();
        //车型id
        List<Integer> vehicleIds = new ArrayList<>();
        carDtoList.forEach(carDto -> {
            vehicleIds.add(carDto.getVehicleId());
            carDtoMap.put(carDto.getVin(), carDto);
        });
        // 查询车型信息
        Map<Integer, String> vehicleFullName = vehicleBizService.getVehicleFullName(vehicleIds);
        //得到 门店-经销商
        Map<Integer, String> map = getDealerStoreNameByStockIds(stockIds);


        //围栏和门店的关系
        Map<Integer, Integer> storeId = fenceStoreStockService.getStoreIdByFenceIds(fenceIds, FenceStoreStockTypeEnum.STORE.getValue());
        for (AlarmInfoDto alarmInfoDto : collect) {
            WarehouseAlarmVo vo = new WarehouseAlarmVo();
            CommonUtils.copyProperties(alarmInfoDto, vo);
            vo.setAlarmType(OUT_FENCE);
            CarDto carDto = carDtoMap.get(vo.getVin());
            if (carDto != null) {
                vo.setCarId(carDto.getId());
                vo.setLicencePlate(carDto.getLicencePlate());
                vo.setVehicleName(vehicleFullName.get(carDto.getVehicleId()));
            }
            Integer id = storeId.get(alarmInfoDto.getFenceInfo().getFenceId().intValue());
            if (id != null) {
                vo.setStockName(map.get(id));
            }
            warehouseAlarmVos.add(vo);
        }
        return warehouseAlarmVos;

    }

    /**
     * 查找数据围栏
     *
     * @param stockIds
     * @return
     */
    private Map<Integer, String> getDealerStoreNameByStockIds(List<Integer> stockIds) {
        Map<Integer, String> stringMap = new HashMap<>();
        try {
            List<Integer> dealerId = new ArrayList<>();
            List<StoreDto> storeListByIds = storeService.getStoreListByIds(stockIds);
            if (CollectionUtils.isEmpty(storeListByIds)) {
                return stringMap;
            }
            for (StoreDto storeDto : storeListByIds) {
                dealerId.add(storeDto.getDealerId());
            }
            Map<Integer, DealerDto> dealerMapByIds = dealerService.getDealerMapByIds(dealerId);
            if (CollectionUtils.isEmpty(dealerMapByIds)) {
                return stringMap;
            }
            for (StoreDto storeDto : storeListByIds) {
                DealerDto dealerDto = dealerMapByIds.get(storeDto.getDealerId());
                if (dealerDto != null) {
                    stringMap.put(storeDto.getStoreId(), dealerDto.getShortName() + "-" + storeDto.getShortName());
                }
            }
            return stringMap;
        } catch (Exception e) {
            e.printStackTrace();
        }
        return stringMap;
    }

    /**
     * 组装中转库数据
     *
     * @param collect
     * @return
     */
    private List<WarehouseAlarmVo> assemblyWarehouseAlarmVoListDate(List<AlarmInfoDto> collect) {
        List<WarehouseAlarmVo> warehouseAlarmVos = new ArrayList<>();
        List<String> vinList = collect.stream().map(AlarmInfoDto::getVin)
                .collect(Collectors.toList());
        //车是否存在
        List<CarDto> carDtoList = carBffService.getByVinList(vinList);
        if (CollectionUtils.isEmpty(carDtoList)) {
            return warehouseAlarmVos;
        }
        Map<String, CarDto> carDtoMap = new HashMap<>();
        //车型id
        List<Integer> vehicleIds = new ArrayList<>();
        carDtoList.forEach(carDto -> {
            vehicleIds.add(carDto.getVehicleId());
            carDtoMap.put(carDto.getVin(), carDto);
        });
        // 查询车型信息
        Map<Integer, String> vehicleFullName = vehicleBizService.getVehicleFullName(vehicleIds);
        //中转库
        List<EntrepotStorageDto> entrepotStorageList = entrepotStorageService.getEntrepotStorageList();
        if (CollectionUtils.isEmpty(entrepotStorageList)) {
            return warehouseAlarmVos;
        }
        Map<Integer, EntrepotStorageDto> storage = entrepotStorageList.stream().
                collect(Collectors.toMap(EntrepotStorageDto::getFenceId, entrepotStorageDto -> entrepotStorageDto));
        log.info("仓储{}", storage);
        for (AlarmInfoDto alarmInfoDto : collect) {
            WarehouseAlarmVo vo = new WarehouseAlarmVo();
            CommonUtils.copyProperties(alarmInfoDto, vo);
            vo.setAlarmType(OUT_FENCE);
            CarDto carDto = carDtoMap.get(vo.getVin());
            if (carDto != null) {
                vo.setCarId(carDto.getId());
                vo.setLicencePlate(carDto.getLicencePlate());
                vo.setVehicleName(vehicleFullName.get(carDto.getVehicleId()));
            }
            EntrepotStorageDto entrepotStorageDto = storage.get(alarmInfoDto.getFenceInfo().getFenceId().intValue());
            if (entrepotStorageDto != null) {
                vo.setStockName(entrepotStorageDto.getShortName());
            }
            warehouseAlarmVos.add(vo);
        }
        return warehouseAlarmVos;
    }

    /**
     * 得到围栏报警
     *
     * @param fenceAlarmList
     * @param alarmType      OUT_FENCE  IN_FENCE
     * @return
     */
    private List<AlarmInfoDto> getFenceAlarmInfo(List<AlarmInfoDto> fenceAlarmList, int alarmType) {
        if (CollectionUtils.isEmpty(fenceAlarmList)) {
            return new ArrayList<>();
        } else {
            return fenceAlarmList.stream().filter(alarmInfoDto -> alarmInfoDto.getAlarmCode().intValue() == alarmType).collect(Collectors.toList());
        }
    }


    /**
     * 组装数据 里程异变
     *
     * @param collect
     * @return
     */
    private List<MileageExAlarmsVo> assemblyMileageExAlarmsVoDate(List<AlarmInfoDto> collect) {
        List<MileageExAlarmsVo> list = new ArrayList<>();

        List<String> vinList = collect.stream().map(AlarmInfoDto::getVin)
                .collect(Collectors.toList());
        List<CarDto> carDtoList = carBffService.getByVinList(vinList);
        if (CollectionUtils.isEmpty(carDtoList)) {
            return list;
        }
        Map<String, CarDto> carDtoMap =
                carDtoList.stream().collect(Collectors.toMap(CarDto::getVin, carDto -> carDto));
        //车的id
        List<Integer> carIds = new ArrayList<>();
        //车型id
        List<Integer> vehicleIds = new ArrayList<>();
        carDtoList.forEach(carDto -> {
            carIds.add(carDto.getId());
            vehicleIds.add(carDto.getVehicleId());
        });
        // 查询车型信息
        Map<Integer, String> vehicleFullName = vehicleBizService.getVehicleFullName(vehicleIds);
        // 用户id集合
        List<Integer> userIds = new ArrayList<>();
        /**
         * 用车中的订单
         */
        Map<Integer, List<CarOrderBizDto>> orderByCar = orderBizService.getOrderByCar(carIds);
        for (AlarmInfoDto alarmInfoDto : collect) {
            MileageExAlarmsVo vo = new MileageExAlarmsVo();
            CommonUtils.copyProperties(alarmInfoDto, vo);
            vo.setLastTimeMileage(alarmInfoDto.getMileageExceptionChange().getLastTimeMileage());
            vo.setCurrentMileage(alarmInfoDto.getMileageExceptionChange().getCurrentMileage());
            vo.setActualMileage(alarmInfoDto.getMileageExceptionChange().getActualMileage());
            vo.setGpsMileage(alarmInfoDto.getMileageExceptionChange().getGpsMileage());
            CarDto carDto = carDtoMap.get(alarmInfoDto.getVin());
            if (carDto != null) {
                vo.setLicencePlate(carDto.getLicencePlate());
                vo.setVehicleName(vehicleFullName.get(carDto.getVehicleId()));
                vo.setCarId(carDto.getId());
                if (CollectionUtils.isEmpty(orderByCar)) {
                    continue;
                }
                List<CarOrderBizDto> carOrderBizDtos = orderByCar.get(carDto.getId());
                log.info("里程异变订单：{}", carOrderBizDtos);
                log.info("报警开始时间：{}", alarmInfoDto.getBeginTime().getTime());
                if (!CollectionUtils.isEmpty(carOrderBizDtos)) {
                    b:
                    for (CarOrderBizDto carOrderBizDto : carOrderBizDtos) {
                        if (carOrderBizDto.getDeliveryTime() == null) {
                            continue;
                        }
                        if (OrderTypeEnum.EXCLUSIVEL.equals(carOrderBizDto.getOrderType())) {
                            // 专属里程订单
                            OrderExclusivelStatusEnum orderStatus = (OrderExclusivelStatusEnum) carOrderBizDto.getOrderStatus();
                            vo.setOrderType(carOrderBizDto.getOrderType().getValue());
                            vo.setOrderStatus(orderStatus.getValue());
                            vo.setOrderTypeStr(carOrderBizDto.getOrderType().getName());
                        } else if (OrderTypeEnum.SUBSCRIBE.equals(carOrderBizDto.getOrderType())) {
                            // 订阅里程订单
                            OrderSubscribeStatusEnum orderStatus = (OrderSubscribeStatusEnum) carOrderBizDto.getOrderStatus();
                            vo.setOrderType(carOrderBizDto.getOrderType().getValue());
                            vo.setOrderStatus(orderStatus.getValue());
                            vo.setOrderTypeStr(carOrderBizDto.getOrderType().getName());
                        }

                        //是否订单内
                        long startTime = carOrderBizDto.getDeliveryTime().toInstant(ZoneOffset.ofHours(8)).toEpochMilli();
                        long endTime = 0;
                        if (carOrderBizDto.getReturnTime() != null) {
                            //已还车
                            endTime = carOrderBizDto.getDeliveryTime().toInstant(ZoneOffset.ofHours(8)).toEpochMilli();
                        } else {
                            //未还车按照下单截止时间算
                            endTime = carOrderBizDto.getLeaseExpire().atStartOfDay(ZoneOffset.ofHours(8)).toInstant().toEpochMilli();
                        }
                        long targetTime = alarmInfoDto.getBeginTime().getTime();

                        if (isRangeTime(startTime, endTime, targetTime)) {
                            vo.setOrderCode(carOrderBizDto.getOrderCode());
                            vo.setUserId(carOrderBizDto.getUserId());
                            userIds.add(carOrderBizDto.getUserId());
                            break b;
                        }

                    }
                }
            }
            list.add(vo);
        }
        if (CollectionUtils.isEmpty(userIds)) {
            return list;
        }
        // 查询用户
        Map<Integer, UserBizDto> userMap = new HashMap<>();
        userMap = userBizService.getUsers(userIds);
        log.info("里程异变订单：{}", userMap);
        if (CollectionUtils.isEmpty(userMap)) {
            return list;
        } else {
            for (MileageExAlarmsVo vo : list) {
                UserBizDto userBizDto = userMap.get(vo.getUserId());
                if (userBizDto != null) {
                    vo.setUserName(userBizDto.getName());
                    vo.setRealName(userBizDto.getRealName());
                    vo.setIdNumber(userBizDto.getIdNumber());
                    vo.setPhone(userBizDto.getPhone());
                }
            }
            return list;
        }
    }

    /**
     * 判断时间戳时候在区间内
     *
     * @param startTime  开始间戳
     * @param endTime    时间戳
     * @param targetTime
     * @return
     */
    public boolean isRangeTime(long startTime, long endTime, long targetTime) {
        if (targetTime > startTime && targetTime <= endTime) {
            return true;
        } else {
            return false;
        }
    }


    /**
     * 组装数据
     *
     * @param iovCarOfflineAlarms
     * @return
     */
    private List<OfflineAlarmVo> assemblyDate(List<IovCarOfflineAlarm> iovCarOfflineAlarms) {
        List<OfflineAlarmVo> list = new ArrayList<>();
        List<String> vinList = iovCarOfflineAlarms.stream().map(IovCarOfflineAlarm::getVin)
                .collect(Collectors.toList());

        List<CarDto> carDtoList = carBffService.getByVinList(vinList);

        if (CollectionUtils.isEmpty(carDtoList)) {
            return list;
        }
        Map<String, CarDto> carDtoMap =
                carDtoList.stream().collect(Collectors.toMap(CarDto::getVin, carDto -> carDto));
        //车的id
        List<Integer> carIds = new ArrayList<>();
        //车型id
        List<Integer> vehicleIds = new ArrayList<>();
        carDtoList.forEach(carDto -> {
            carIds.add(carDto.getId());
            vehicleIds.add(carDto.getVehicleId());
        });
        // 查询车型信息
        Map<Integer, String> vehicleFullName = vehicleBizService.getVehicleFullName(vehicleIds);
        // 用户id集合
        List<Integer> userIds = new ArrayList<>();
        List<Integer> storeIds = new ArrayList<>();
        /**
         * 用车中的订单
         */
        Map<Integer, CarOrderBizDto> useOrder = orderBizService.getUseOrderByCar(carIds);
        if (!CollectionUtils.isEmpty(useOrder)) {
            for (CarOrderBizDto bizDto : useOrder.values()) {
                storeIds.add(bizDto.getDeliveryStoreId());
                userIds.add(bizDto.getUserId());
            }
        }
        //得到 门店-经销商
        Map<Integer, String> map = getDealerStoreNameByStockIds(storeIds);
        // 查询用户
        Map<Integer, UserBizDto> userMap = new HashMap<>();
        userMap = userBizService.getUsers(userIds);
        for (IovCarOfflineAlarm iovCarOfflineAlarm : iovCarOfflineAlarms) {
            OfflineAlarmVo vo = new OfflineAlarmVo();
            CommonUtils.copyProperties(iovCarOfflineAlarm, vo);
            vo.setLastReportDate(iovCarOfflineAlarm.getLastReportDate());
            CarDto carDto = carDtoMap.get(iovCarOfflineAlarm.getVin());
            if (carDto != null) {
                vo.setLicencePlate(carDto.getLicencePlate());
                vo.setVehicleName(vehicleFullName.get(carDto.getVehicleId()));
                vo.setCarId(carDto.getId());
                if (!CollectionUtils.isEmpty(useOrder)) {
                    CarOrderBizDto bizDto = useOrder.get(carDto.getId());
                    if (bizDto != null) {
                        vo.setOrderCode(bizDto.getOrderCode());
                        if (OrderTypeEnum.EXCLUSIVEL.equals(bizDto.getOrderType())) {
                            // 专属里程订单
                            OrderExclusivelStatusEnum orderStatus = (OrderExclusivelStatusEnum) bizDto.getOrderStatus();
                            vo.setOrderType(bizDto.getOrderType().getValue());
                            vo.setOrderStatus(orderStatus.getValue());
                            vo.setOrderTypeStr(bizDto.getOrderType().getName());
                        } else if (OrderTypeEnum.SUBSCRIBE.equals(bizDto.getOrderType())) {
                            // 订阅里程订单
                            OrderSubscribeStatusEnum orderStatus = (OrderSubscribeStatusEnum) bizDto.getOrderStatus();
                            vo.setOrderType(bizDto.getOrderType().getValue());
                            vo.setOrderStatus(orderStatus.getValue());
                            vo.setOrderTypeStr(bizDto.getOrderType().getName());
                        }
                        vo.setDeliveryStoreName(map.get(bizDto.getDeliveryStoreId()));
                        UserBizDto userBizDto = userMap.get(bizDto.getUserId());
                        if (userBizDto != null) {
                            vo.setUserName(userBizDto.getName());
                            vo.setRealName(userBizDto.getRealName());
                            vo.setIdNumber(userBizDto.getIdNumber());
                            vo.setPhone(userBizDto.getPhone());
                        }
                    }
                }

            }
            list.add(vo);
        }
        return list;
    }
}
